package com.e3.template.tgf;

import com.e3.web.core.client.CommonMessages;
import com.e3.web.core.client.EditorListener;
import com.e3.web.core.client.GXTHelper;
import com.e3.web.core.client.GwtAsyncCallback;
import com.e3.web.core.client.ListenerManager;
import com.e3.web.core.model.SuperModel;
import com.e3.web.widget.client.MyDialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.user.client.Element;

public abstract class TGFEditorDialog<D extends SuperModel> extends MyDialog {
	
	protected ListenerManager<D> listenerManager = new ListenerManager<D>();
	
	private TGFMessages TGFMESSAGES = TGFMessages.INSTANCE;
	
	private boolean isNew = true;
	
	private TGFFormPanel<D> formPanel;
	
	private GwtAsyncCallback<D> callback;
	
	@Override
	protected void onRender(Element parent, int pos) {
		super.onRender(parent, pos);
		this.setSize(400, 350);
		setLayout(new FitLayout());
		add(getFormPanel());
		setOKText(TGFMESSAGES.action_save());
	}
	
	public void addEditorListener(EditorListener<D> listener){
		listenerManager.addEditorListener(listener);
	}
	
	public void showDialog(D model,String localName,boolean isNew){
		this.isNew = isNew;
		if(isNew){
			this.setHeading(TGFMESSAGES.title_new(localName));
		}
		else{
			this.setHeading(TGFMESSAGES.title_modify(model.toString()));
		}
		this.setVisible(true);
		getFormPanel().setFormValue(model);
	}

	private TGFFormPanel<D> getFormPanel() {
		if(formPanel == null){
			formPanel = createFormPanel();
			formPanel.setFormReadonly(false);
		}
		return formPanel;
	}
	
	@Override
	protected void onOk() {
		D model = getFormPanel().getFormValue();
		if(model == null){
			setVisible(false);
			return;
		}
		
		String msgs = checkOnSave(model);
		if(msgs!=null&&msgs.length()>0){
			MessageBox.alert(TGFMESSAGES.msgbox_alert_title(), msgs, null);
			return;
		}
		
		GXTHelper.maskSave(this);
		 GwtAsyncCallback<D> callback = getEditorAsyncCallBack();
		if(isNew){
			executeNewService(model, callback);
		}
		else{
			executeModifyService(model, callback);
		}
	}
	
	public void onSaveSuccess(D model){
		listenerManager.notifyEditorSuccess(model);
		setVisible(false);
	}
	
	public GwtAsyncCallback<D> getEditorAsyncCallBack(){
		if(callback == null){
			callback = new GwtAsyncCallback<D>(this) {
				@Override
				public void doSuccess(D result) {
					onSaveSuccess(result);
				}
			};
		}
		return callback; 
	}

	public String checkOnSave(D model){
		String[] fNames = getNotNullFieldNames();
		if(fNames == null || fNames.length==0){
			return null;
		}
		StringBuffer msgs = new StringBuffer();
		for (String fName : fNames) {
			Object value = model.get(fName);
			if(value == null){
				Field<?> field = getFormPanel().getFormFieldByName(fName);
				msgs.append(field.getFieldLabel()+",");
			}
		}
		String s  = null;
		if(msgs.length()>0){
			s = msgs.substring(0,msgs.length()-1);
		}
		if(s != null){
			return CommonMessages.INSTANCE.msg_notnull(s);
		}
		return null;
	}

	public abstract TGFFormPanel<D> createFormPanel();
	
	public abstract void executeNewService(D model, GwtAsyncCallback<D> callback);
	
	public abstract void executeModifyService(D model, GwtAsyncCallback<D> callback);
	
	public abstract String[] getNotNullFieldNames();
}
